成品連結:Follow Along Link Highlighter、操作前程式碼、完成後程式碼
今天要做的效果是當滑鼠 hover 至特定文字上時出現 highlight 的效果
我原本以為在 mouseenter
事件時加入 highlight
的 class 屬性就好,但後來發現這樣並不會有成品的效果;且從 CSS 可以看到 highlight
已設定 position: absolute
,因此如果用我原本的方式被 mouseenter
的元素會跑到左上角,需要尋求其他辦法。以下解說~
首先把所有的 a
元素存入變數
const triggers = document.querySelectorAll('a');
span
以顯示 highlight 效果接著我們要創建新的元素 span
來顯示 highlight
的效果,所以要加上 highlight
的 class,並放到 HTML 當中
const highlight = document.createElement('span');
highlight.classList.add('highlight');
document.body.append(highlight);
此時 HTML 當中可以看到新建的元素,但畫面上卻看不到,因為我們還沒定義寬、高。
設定當滑鼠進入 a
時的事件
triggers.forEach(a => a.addEventListener('mouseenter', highlightLinks));
接著要完善 callback 的內容
function highlightLinks() {
// code here
}
重點來了,這裡我們要使用 getBoundingClientRect()
來取得該 a
元素的寬、高以及之於左上角的位置,使用 console.log(this)
可以看到如下資訊
我們可以善用這些資訊來設定剛剛創建的 span
的大小及位置
function highlightLinks() {
const linkCoords = this.getBoundingClientRect(); // 取得大小、位置資訊
highlight.style.width = `${coords.width}px`;
highlight.style.height = `${coords.height}px`;
highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)`
}
highlight
似乎會跑掉?如成品的效果成功做出來了!但有個小問題,當滾動捲軸時 highlight
的效果會跑掉,這是因為當畫面載入時元素的位置(也就是 getBoundingClientRect()
所獲得的資訊)已經固定,當滾動捲軸時並不會自動更新資訊。
解決辦法是加上滾動的距離(X 軸及 Y 軸都要),而滾動的距離我們可以透過 window.scrollX
以及 window.scrollY
取得
為避免 code 雜亂,我們新建一個 object 來儲存 highlight
所需要的資料
const coords = {
width: linkCoords.width,
height: linkCoords.height,
top: linkCoords.top + window.scrollY,
left: linkCoords.left + window.scrollX
}
並更新剛剛 highlight
的設定
highlight.style.width = `${coords.width}px`;
highlight.style.height = `${coords.height}px`;
highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)`
完成!